package cn.julbreeze.framework.common.utils;

import cn.julbreeze.framework.common.constant.DateConstants;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @date: 2025/3/6
 * description:  JSON 工具类 (依赖 jackson-databind 库)
 *               功能：安全转换、深拷贝、合并、路径查询、格式化等
 */

public class JsonUtils {
    private static ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static {
        // 配置美化输出、空值处理等
        OBJECT_MAPPER.enable(SerializationFeature.INDENT_OUTPUT);
        OBJECT_MAPPER.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);// 序列化时允许空对象
        // 下面注释掉的两行代码 完全等同于 上面的两行代码
//        OBJECT_MAPPER.configure(SerializationFeature.INDENT_OUTPUT, true);
//        OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);// 反序列化时忽略未知属性
//        OBJECT_MAPPER.registerModules(new JavaTimeModule()); // 解决 LocalDateTime 的序列化问题

        // JavaTimeModule 用于指定序列化和反序列化规则
        JavaTimeModule javaTimeModule = new JavaTimeModule();

        // 支持 LocalDateTime
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DateConstants.Y_M_D_H_M_S_FORMAT)));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DateConstants.Y_M_D_H_M_S_FORMAT)));

        OBJECT_MAPPER.registerModules(javaTimeModule); // 解决 LocalDateTime 的序列化问题

    }

    /**
     * 初始化：统一使用 Spring Boot 个性化配置的 ObjectMapper
     *
     * @param objectMapper
     */
    public static void init(ObjectMapper objectMapper) {
        OBJECT_MAPPER = objectMapper;
    }

    /**
     * 对象转 JSON 字符串
     * @param obj Java 对象
     * @return JSON 字符串，转换失败返回空字符串
     */
    public static String toJsonString(Object obj) {
        try {
            return OBJECT_MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            return "";
        }
    }

    /**
     * JSON 字符串转对象
     * @param json JSON 字符串
     * @param clazz 目标类型
     * @return 转换失败返回 null
     */
    public static <T> T fromJson(String json, Class<T> clazz) {
        try {
            return OBJECT_MAPPER.readValue(json, clazz);
        } catch (JsonProcessingException e) {
            return null;
        }
    }

    /**
     * 深拷贝对象
     * @param source 源对象
     * @param typeRef 目标类型引用 (用于泛型)
     * @return 拷贝后的新对象
     */
    public static <T> T deepClone(T source, TypeReference<T> typeRef) {
        try {
            return OBJECT_MAPPER.readValue(toJsonString(source), typeRef);
        } catch (JsonProcessingException e) {
            return null;
        }
    }

    /**
     * 合并两个 JSON 对象
     * @param target 目标对象 (会被修改)
     * @param source 源对象
     */
    public static void merge(ObjectNode target, ObjectNode source) {
        source.fields().forEachRemaining(entry -> {
            JsonNode targetNode = target.get(entry.getKey());
            if (targetNode instanceof ObjectNode && entry.getValue() instanceof ObjectNode) {
                merge((ObjectNode) targetNode, (ObjectNode) entry.getValue());
            } else if (targetNode instanceof ArrayNode && entry.getValue() instanceof ArrayNode) {
                ((ArrayNode) targetNode).addAll((ArrayNode) entry.getValue());
            } else {
                target.set(entry.getKey(), entry.getValue());
            }
        });
    }

    /**
     * 根据路径获取值
     * @param json JSON 字符串
     * @param path 路径表达式 (如 "user.address.city")
     * @return 路径对应的值，找不到返回 null
     */
    public static JsonNode getValueByPath(String json, String path) {
        try {
            JsonNode root = OBJECT_MAPPER.readTree(json);
            String[] keys = path.split("\\.");
            for (String key : keys) {
                if (root == null) break;
                root = root.get(key);
            }
            return root;
        } catch (JsonProcessingException e) {
            return null;
        }
    }

    /**
     * 验证 JSON 是否合法
     * @param json JSON 字符串
     * @return 是否有效
     */
    public static boolean isValid(String json) {
        try {
            OBJECT_MAPPER.readTree(json);
            return true;
        } catch (JsonProcessingException e) {
            return false;
        }
    }

    /**
     * 动态创建 JSON 对象
     * @return 空 JSON 对象
     */
    public static ObjectNode createObjectNode() {
        return OBJECT_MAPPER.createObjectNode();
    }

    /**
     * 动态创建 JSON 数组
     * @return 空 JSON 数组
     */
    public static ArrayNode createArrayNode() {
        return OBJECT_MAPPER.createArrayNode();
    }

    /**
     * 配置全局 ObjectMapper (如日期格式)
     * @param config 自定义配置函数
     */
    public static void configMapper(CustomMapperConfig config) {
        config.configure(OBJECT_MAPPER);
    }

    @FunctionalInterface
    public interface CustomMapperConfig {
        void configure(ObjectMapper OBJECT_MAPPER);
    }
}
